package net.lab1024.sa.admin.module.business.aps.domain.optaplanner;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * OptaPlanner时间槽实体
 * 用于APS排程优化的时间段定义
 *
 * @Author 1024创新实验室
 * @Date 2025-01-28
 * @Wechat zhuoda1024
 * @Email lab1024@163.com
 * @Copyright <a href="https://1024lab.net">1024创新实验室</a>
 */
@Data
@NoArgsConstructor
public class TimeSlot {

    /**
     * 时间槽ID
     */
    private Long timeSlotId;

    /**
     * 开始时间
     */
    private LocalDateTime startTime;

    /**
     * 时间槽长度（分钟）
     */
    private Integer durationMinutes;

    /**
     * 时间槽类型（NORMAL, OVERTIME, WEEKEND等）
     */
    private String slotType;

    /**
     * 成本系数（加班时间成本更高）
     */
    private Double costFactor;

    /**
     * 是否可用
     */
    private Boolean available;

    /**
     * 构造函数
     */
    public TimeSlot(Long timeSlotId, LocalDateTime startTime, Integer durationMinutes, 
                   String slotType, Double costFactor, Boolean available) {
        this.timeSlotId = timeSlotId;
        this.startTime = startTime;
        this.durationMinutes = durationMinutes;
        this.slotType = slotType;
        this.costFactor = costFactor;
        this.available = available;
    }

    /**
     * 获取结束时间
     */
    public LocalDateTime getEndTime() {
        return startTime.plusMinutes(durationMinutes);
    }

    /**
     * 检查是否与另一个时间槽重叠
     */
    public boolean isOverlapping(TimeSlot other) {
        if (other == null) {
            return false;
        }
        LocalDateTime thisEnd = this.getEndTime();
        LocalDateTime otherEnd = other.getEndTime();
        
        return !(thisEnd.isBefore(other.startTime) || this.startTime.isAfter(otherEnd));
    }

    /**
     * 检查是否与指定时间段重叠
     */
    public boolean isOverlapping(LocalDateTime checkStart, LocalDateTime checkEnd) {
        LocalDateTime thisEnd = this.getEndTime();
        return !(thisEnd.isBefore(checkStart) || this.startTime.isAfter(checkEnd));
    }

    /**
     * 检查是否能容纳指定持续时间的任务
     */
    public boolean canAccommodateTask(Integer taskDuration) {
        return available && durationMinutes >= taskDuration;
    }

    /**
     * 计算与另一个时间槽的时间间隔（分钟）
     */
    public long getMinutesUntil(TimeSlot other) {
        if (other == null) {
            return Long.MAX_VALUE;
        }
        return java.time.Duration.between(this.getEndTime(), other.startTime).toMinutes();
    }

    /**
     * 获取时间槽的显示标签
     */
    public String getDisplayLabel() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd HH:mm");
        return String.format("%s-%s (%s)", 
                startTime.format(formatter), 
                getEndTime().format(formatter), 
                slotType);
    }

    /**
     * 检查是否为工作时间
     */
    public boolean isWorkingHours() {
        return "NORMAL".equals(slotType);
    }

    /**
     * 检查是否为加班时间
     */
    public boolean isOvertime() {
        return "OVERTIME".equals(slotType);
    }

    /**
     * 检查是否为周末时间
     */
    public boolean isWeekend() {
        return "WEEKEND".equals(slotType);
    }

    @Override
    public String toString() {
        return getDisplayLabel();
    }
}